"""
图书阅读位置接口测试
测试阅读位置的更新和查询功能
"""

import requests
import json
import time

base_url = "http://localhost:8080/api"
reading_positions_url = f"{base_url}/reading-positions"
users_url = f"{base_url}/users"


def login_user(username, password):
    """用户登录并返回token"""
    login_data = {"username": username, "password": password}
    response = requests.post(
        f"{users_url}/login",
        json=login_data,
        headers={"Content-Type": "application/json"},
    )
    if response.status_code == 200:
        return response.json().get("token")
    else:
        print(f"登录失败: {response.json()}")
        return None


def register_user(username, password):
    """用户注册"""
    register_data = {"username": username, "password": password}
    response = requests.post(
        f"{users_url}/register",
        json=register_data,
        headers={"Content-Type": "application/json"},
    )
    return response.status_code == 200


def test_reading_positions_info():
    """测试获取阅读位置管理接口信息"""
    print("=== 测试获取阅读位置管理接口信息 ===")

    try:
        response = requests.get(f"{reading_positions_url}/")

        print(f"状态码: {response.status_code}")
        print(f"响应内容: {json.dumps(response.json(), ensure_ascii=False, indent=2)}")

        if response.status_code == 200:
            print("✅ 获取阅读位置接口信息成功")
            return True
        else:
            print("❌ 获取阅读位置接口信息失败")
            return False

    except Exception as e:
        print(f"❌ 获取阅读位置接口信息请求异常: {e}")
        return False


def test_update_reading_position(token, book_id=1, position=100):
    """测试更新阅读位置"""
    print(f"\n=== 测试更新阅读位置 (book_id: {book_id}, position: {position}) ===")

    if not token:
        print("❌ 没有有效的token，跳过测试")
        return False

    headers = {
        "Authorization": f"Bearer {token}",
        "Content-Type": "application/json",
    }

    data = {"book_id": book_id, "position": position}

    try:
        response = requests.post(
            f"{reading_positions_url}/update", json=data, headers=headers
        )

        print(f"状态码: {response.status_code}")
        print(f"响应内容: {json.dumps(response.json(), ensure_ascii=False, indent=2)}")

        if response.status_code == 200:
            print("✅ 更新阅读位置成功")
            return True
        else:
            print("❌ 更新阅读位置失败")
            return False

    except Exception as e:
        print(f"❌ 更新阅读位置请求异常: {e}")
        return False


def test_get_reading_position(token, book_id=1):
    """测试获取阅读位置"""
    print(f"\n=== 测试获取阅读位置 (book_id: {book_id}) ===")

    if not token:
        print("❌ 没有有效的token，跳过测试")
        return False

    headers = {
        "Authorization": f"Bearer {token}",
        "Content-Type": "application/json",
    }

    try:
        response = requests.get(
            f"{reading_positions_url}/get?book_id={book_id}", headers=headers
        )
        
        print(f"状态码: {response.status_code}")
        print(f"响应内容: {json.dumps(response.json(), ensure_ascii=False, indent=2)}")
        
        if response.status_code == 200:
            print("✅ 获取阅读位置成功")
            # 从正确的字段中获取阅读位置数据
            response_data = response.json()
            if "reading_positions_data" in response_data:
                return response_data["reading_positions_data"]
            else:
                return response_data  # 兼容性处理
        elif response.status_code == 404:
            print("✅ 未找到阅读记录（预期行为）")
            return None
        else:
            print("❌ 获取阅读位置失败")
            return False

    except Exception as e:
        print(f"❌ 获取阅读位置请求异常: {e}")
        return False


def test_get_nonexistent_reading_position(token, book_id=999):
    """测试获取不存在的阅读位置"""
    print(f"\n=== 测试获取不存在的阅读位置 (book_id: {book_id}) ===")

    if not token:
        print("❌ 没有有效的token，跳过测试")
        return False

    headers = {
        "Authorization": f"Bearer {token}",
        "Content-Type": "application/json",
    }

    try:
        response = requests.get(
            f"{reading_positions_url}/get?book_id={book_id}", headers=headers
        )

        print(f"状态码: {response.status_code}")
        print(f"响应内容: {response.json()}")

        if response.status_code == 404:
            print("✅ 获取不存在阅读位置验证成功")
            return True
        else:
            print("❌ 获取不存在阅读位置验证失败")
            return False

    except Exception as e:
        print(f"❌ 获取不存在阅读位置请求异常: {e}")
        return False


def test_update_reading_position_multiple_times(token, book_id=1):
    """测试多次更新同一本书的阅读位置"""
    print(f"\n=== 测试多次更新同一本书的阅读位置 (book_id: {book_id}) ===")

    positions = [50, 100, 150, 200]

    for i, position in enumerate(positions):
        print(f"\n第{i+1}次更新，位置: {position}")
        success = test_update_reading_position(token, book_id, position)
        if not success:
            return False

        # 验证更新结果
        result = test_get_reading_position(token, book_id)
        if result and result.get("position") == position:
            print(f"✅ 位置更新验证成功: {position}")
        else:
            print(
                f"❌ 位置更新验证失败: 期望{position}, 实际{result.get('position') if result else 'None'}"
            )
            return False

    print("✅ 多次更新阅读位置测试成功")
    return True


def test_unauthorized_access():
    """测试未授权访问"""
    print("\n=== 测试未授权访问 ===")

    try:
        # 测试没有token的情况
        data = {"book_id": 1, "position": 100}
        response = requests.post(f"{reading_positions_url}/update", json=data)
        print(f"无token更新 - 状态码: {response.status_code}")

        response = requests.get(f"{reading_positions_url}/get?book_id=1")
        print(f"无token获取 - 状态码: {response.status_code}")

        # 测试无效token的情况
        headers = {"Authorization": "Bearer invalid_token"}
        response = requests.post(
            f"{reading_positions_url}/update", json=data, headers=headers
        )
        print(f"无效token更新 - 状态码: {response.status_code}")

        if response.status_code == 401:
            print("✅ 未授权访问验证成功")
            return True
        else:
            print("❌ 未授权访问验证失败")
            return False

    except Exception as e:
        print(f"❌ 未授权访问测试异常: {e}")
        return False


def test_invalid_parameters(token):
    """测试无效参数"""
    print("\n=== 测试无效参数 ===")

    if not token:
        print("❌ 没有有效的token，跳过测试")
        return False

    headers = {
        "Authorization": f"Bearer {token}",
        "Content-Type": "application/json",
    }

    try:
        # 测试缺少book_id
        data = {"position": 100}
        response = requests.post(
            f"{reading_positions_url}/update", json=data, headers=headers
        )
        print(f"缺少book_id - 状态码: {response.status_code}")

        # 测试缺少position
        data = {"book_id": 1}
        response = requests.post(
            f"{reading_positions_url}/update", json=data, headers=headers
        )
        print(f"缺少position - 状态码: {response.status_code}")

        # 测试无效的book_id参数（获取时）
        response = requests.get(f"{reading_positions_url}/get", headers=headers)
        print(f"缺少book_id参数 - 状态码: {response.status_code}")

        if response.status_code == 422:  # FastAPI参数验证错误
            print("✅ 无效参数验证成功")
            return True
        else:
            print("❌ 无效参数验证失败")
            return False

    except Exception as e:
        print(f"❌ 无效参数测试异常: {e}")
        return False


def run_all_reading_positions_tests():
    """运行所有阅读位置测试"""
    print("开始阅读位置功能测试...")
    print("=" * 70)

    # 测试用户名（使用时间戳确保唯一性）
    username = f"reading_test_user_{int(time.time())}"
    password = "123456"

    # 1. 注册测试用户
    print(f"注册测试用户: {username}")
    if not register_user(username, password):
        print("❌ 用户注册失败，测试终止")
        return

    # 2. 登录获取token
    print(f"登录测试用户: {username}")
    token = login_user(username, password)
    if not token:
        print("❌ 用户登录失败，测试终止")
        return

    print(f"✅ 获得token: {token[:20]}...")

    # 3. 测试获取阅读位置接口信息
    test_reading_positions_info()

    # 4. 测试未授权访问
    test_unauthorized_access()

    # 5. 测试无效参数
    test_invalid_parameters(token)

    # 6. 测试获取不存在的阅读位置
    test_get_nonexistent_reading_position(token, book_id=1)

    # 7. 测试更新阅读位置
    test_update_reading_position(token, book_id=1, position=50)
    test_update_reading_position(token, book_id=2, position=75)
    test_update_reading_position(token, book_id=3, position=120)

    # 8. 测试获取阅读位置
    test_get_reading_position(token, book_id=1)
    test_get_reading_position(token, book_id=2)
    test_get_reading_position(token, book_id=3)

    # 9. 测试多次更新同一本书的阅读位置
    test_update_reading_position_multiple_times(token, book_id=1)

    # 10. 测试获取不存在的图书阅读位置
    test_get_nonexistent_reading_position(token, book_id=999)

    # 11. 验证最终状态
    print(f"\n=== 验证最终阅读位置状态 ===")
    test_get_reading_position(token, book_id=1)  # 应该是200
    test_get_reading_position(token, book_id=2)  # 应该是75
    test_get_reading_position(token, book_id=3)  # 应该是120

    print("\n" + "=" * 70)
    print("阅读位置功能测试完成")


if __name__ == "__main__":
    run_all_reading_positions_tests()
